﻿using System;
using System.Drawing;
using System.Windows.Forms;
using Model.LiveControl;

namespace Managers.LiveControl.Client
{
    public class MousePolicy: PolicyDecorator
    {
        private IBoundsSetor _gdiScreenBoundsSetor;
        private Rectangle _screenRectangle;
        private bool _flagOnlyShowForm = false;

        public MousePolicy(IBoundsSetor gdiScreenBoundsSetor)
        {
            _gdiScreenBoundsSetor = gdiScreenBoundsSetor;
        }

        private bool flagShowStatusChanged = false;

        public bool FlagOnlyShowForm
        {
            get { return _flagOnlyShowForm; }
            set
            {
                if (_flagOnlyShowForm != value)
                {
                    _flagOnlyShowForm = value;
                    flagShowStatusChanged = true;
                }
            }
        }

        public Rectangle ScreenRectangle
        {
            set
            {
                if (!flagShowStatusChanged && _screenRectangle == value)
                {
                    return;
                }
                _screenRectangle = value;

                if (!FlagOnlyShowForm)
                {
                    SetShowableRect(_screenRectangle);
                }
               
            }
            private get { return _screenRectangle; }
        }

        private Rectangle RealFormRectangle { set;  get; }

        private Rectangle ShowFormRectangle => _gdiScreenBoundsSetor.CoustomBounds;

        public void SetRealFormRect(Rectangle tRectangle)
        {

            if (!flagShowStatusChanged && RealFormRectangle == tRectangle)
            {
                return;
            }

            RealFormRectangle = tRectangle;
            if (FlagOnlyShowForm)
                SetShowableRect(tRectangle);
        }

        private void SetShowableRect(Rectangle tRectangle)
        {
            var clientWorkArea = Screen.GetWorkingArea(_gdiScreenBoundsSetor.CoustomBounds);
            // 保持一定像素的边距
            clientWorkArea.Width -= 10;
            clientWorkArea.Height -= 10;

            double whRatioRealForm = tRectangle.Width / (double) tRectangle.Height;
            double whRatioWorkArea = clientWorkArea.Width / (double) clientWorkArea.Height;


            int width;
            int height;
            if (whRatioRealForm > whRatioWorkArea)
            {
                if (tRectangle.Width > clientWorkArea.Width)
                {
                    width = clientWorkArea.Width;
                    height = (int) (width / whRatioRealForm);
                }
                else
                {
                    width = tRectangle.Width;
                    height = tRectangle.Height;
                }
            }
            else
            {
                if (tRectangle.Height > clientWorkArea.Height)
                {
                    height = clientWorkArea.Height;
                    width = (int) (height * whRatioRealForm);
                }
                else
                {
                    width = tRectangle.Width;
                    height = tRectangle.Height;
                }
            }
            int x = (clientWorkArea.Width - width) / 2;
            int y = (clientWorkArea.Height - height) / 2;
            var showFormRectangle = new Rectangle(x, y, width, height);
            _gdiScreenBoundsSetor.CoustomBounds = showFormRectangle;
            flagShowStatusChanged = false;
        }

        /// <summary>
        /// 显示单窗时对鼠标坐标的变换
        /// </summary>
        /// <param name="args">鼠标事件参数</param>
        /// <param name="rectShowForm">显示端窗口边框</param>
        /// <param name="rectRealForm">服务端真实窗口边框大小，且减去了窗口所在分屏的左上角坐标</param>
        /// <param name="rectScreen">服务端屏幕大小</param>
        /// <returns></returns>
        private CoustomMouseEventArgs MouseArgsRevise(MouseEventArgs args, Rectangle rectShowForm, Rectangle rectRealForm,
            Rectangle rectScreen)
        {
            int x = args.X;
            int y = args.Y;


            double ratioX =(x / (double)rectShowForm.Width * rectRealForm.Width + rectRealForm.X) / rectScreen.Width;
            double ratioY =(y / (double)rectShowForm.Height * rectRealForm.Height + rectRealForm.Y) / rectScreen.Height;

            CoustomMouseEventArgs tCoustomArgs = new CoustomMouseEventArgs(ratioX,ratioY,args);

            return tCoustomArgs;
        }

        /// <summary>
        /// 显示全屏时对坐标的变换
        /// </summary>
        /// <param name="args">鼠标事件参数</param>
        /// <param name="rectShowForm">窗口边框</param>
        /// <returns></returns>
        private CoustomMouseEventArgs MouseArgsRevise(MouseEventArgs args, Rectangle rectShowForm)
        {

            double ratioX = args.X / (double)rectShowForm.Width ;
            double ratioY = args.Y / (double)rectShowForm.Height ;
            CoustomMouseEventArgs tCoustomArgs = new CoustomMouseEventArgs(ratioX, ratioY, args);

            return tCoustomArgs;
        }

        public override  CoustomMouseEventArgs MouseArgsRevise(MouseEventArgs args)
        {
            return FlagOnlyShowForm ? 
                MouseArgsRevise(args, ShowFormRectangle,RealFormRectangle,ScreenRectangle) : 
                MouseArgsRevise(args, ShowFormRectangle);
        }

        public void ResetBound()
        {
            if (!FlagOnlyShowForm)
            {
                SetShowableRect(_screenRectangle);
            }
        }
    }

    
}